<?php
/**
 * Created by PhpStorm.
 * User: dong
 * Date: 2018/3/9
 * Time: 21:16
 */
namespace App\Services\ThirdPayments\Recharge;

use App\Exceptions\RechargeGatewayException;
use App\Lib\Code;
use App\Lib\PaymentMap;
use App\Lib\ThirdPartyMap;
use App\Models\RechargeOrder;
use App\Services\ThirdPayments\BankTraits\TJFBankMap;
use App\Services\ThirdPayments\Contracts\Actions\HrefRedirectAction;
use App\Services\ThirdPayments\Contracts\Actions\HtmlPrintAction;
use App\Services\ThirdPayments\Contracts\Actions\QrCodeAction;
use App\Services\ThirdPayments\Contracts\QRCapable;
use App\Services\ThirdPayments\Contracts\RechargeBaseAbstract;
use App\Services\ThirdPayments\Contracts\WAPable;
use Illuminate\Support\Facades\Log;

class TJFPayment extends RechargeBaseAbstract implements QRCapable, WAPable
{
    use TJFBankMap;

    protected $gw_pay = 'http://gate.iceuptrade.com/cooperate/gateway.cgi';

    public function callback(array $data)
    {
        // TODO: Implement callback() method.
        if ($this->veryCallbackSign($data)) {
            if ($data['status'] == 1) return true;
        }
        return false;
    }

    public function veryCallbackSign(array $data)
    {
        // TODO: Implement veryCallbackSign() method.
        $parseStr = "service=" . $data['service'] . '&';
        $parseStr .= "merId=" . $data['merId'] . '&';
        $parseStr .= "tradeNo=" . $data['tradeNo'] . '&';
        $parseStr .= "tradeDate=" . $data['tradeDate'] . '&';
        $parseStr .= "opeNo=" . $data['opeNo'] . '&';
        $parseStr .= "opeDate=" . $data['opeDate'] . '&';
        $parseStr .= "amount=" . $data['amount'] . '&';
        $parseStr .= "status=" . $data['status'] . '&';
        $parseStr .= "extra=" . $data['extra'] . '&';
        $parseStr .= "payTime=" . $data['payTime'];
        $parseStr .= $this->getMchKey();
        if (strtoupper(md5($parseStr)) == $data['sign']) {
            return true;
        }
        return false;
    }

    public function getOrderNoFromCallback(array $data)
    {
        // TODO: Implement getOrderNoFromCallback() method.
        return $data['tradeNo'];
    }

    public function getThirdNoFromCallback(array $data)
    {
        return $data['opeNo'];
    }

    public function getOrderAmtFromCallback(array $data)
    {
        // TODO: Implement getOrderAmtFromCallback() method.
        return $data['amount'];
    }

    /**
     * @return mixed
     */
    public function getIdentify(): string
    {
        // TODO: Implement getIdentify() method.
        return ThirdPartyMap::TIANJF;
    }

    /**
     *  needs child to achieve
     */
    public function initPaymentMap(): array
    {
        // TODO: Implement initPaymentMap() method.
        return [
            PaymentMap::WX => 2,
            PaymentMap::ALI => 1,
            PaymentMap::QQ => 3,
            PaymentMap::BANK_SCAN => 4,
            PaymentMap::WX_WAP => 2,
            PaymentMap::ALI_WAP => 1,
            PaymentMap::QQ_WAP => 3
        ];

    }

    public function query(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement query() method.
    }

    public function bankHref(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement bankHref() method.
        $this->setParameter('service', 'TRADE.B2C');
        $this->setParameter('version', '1.0.0.0');
        $this->setParameter('merId', $this->getMchId());
        $this->setParameter('tradeNo', $rechargeOrder->plat_no);
        $this->setParameter('tradeDate', date('Ymd'));
        $this->setParameter('amount', $rechargeOrder->order_amt);
        $this->setParameter('notifyUrl', $this->getCallbackUrl());
        $this->setParameter('extra', $this->setRemark($rechargeOrder));
        $this->setParameter('summary', "uuupays");
        $this->setParameter('clientIp', request()->getClientIp());
        $this->setParameter('bankId', $this->getBank($rechargeOrder->order_data['bank_code']));
        $this->setParameter('sign', $this->getBankSign());
        return new HtmlPrintAction(formPostHtml($this->getGwPay(), $this->getParameters()));
    }

    public function scanCode(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement scanCode() method.
        $this->initParameters($rechargeOrder);
        $this->setParameter('service', 'TRADE.SCANPAY');
        $this->setParameter('sign', $this->paySign());
    }

    public function paySign(): string
    {
        // TODO: Implement paySign() method.
        $signStr = 'service=' . $this->getParameter('service') . '&';
        $signStr .= 'version=' . $this->getParameter('version') . '&';
        $signStr .= 'merId=' . $this->getParameter('merId') . '&';
        $signStr .= 'typeId=' . $this->getParameter('typeId') . '&';
        $signStr .= 'tradeNo=' . $this->getParameter('tradeNo') . '&';
        $signStr .= 'tradeDate=' . $this->getParameter('tradeDate') . '&';
        $signStr .= 'amount=' . $this->getParameter('amount') . '&';
        $signStr .= 'notifyUrl=' . $this->getParameter('notifyUrl') . '&';
        $signStr .= 'extra=' . $this->getParameter('extra') . '&';
        $signStr .= 'summary=' . $this->getParameter('summary') . '&';
        $signStr .= 'clientIp=' . $this->getParameter('clientIp');
        $signStr .= $this->getMchKey();
        return strtoupper(md5($signStr));
    }

    public function querySign(): string
    {
        // TODO: Implement querySign() method.
    }


    public function showSuccess(): string
    {
        // TODO: Implement showSuccess() method.
        return 'SUCCESS';
    }

    public function initParameters(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement initParameters() method.
        $this->setParameter('version', '1.0.0.0');
        $this->setParameter('merId', $this->getMchId());
        $this->setParameter('typeId', $this->getPaymentMap($rechargeOrder->order_data['recharge_type']));
        $this->setParameter('tradeNo', $rechargeOrder->plat_no);
        $this->setParameter('tradeDate', date('Ymd'));
        $this->setParameter('amount', $rechargeOrder->order_amt);
        $this->setParameter('notifyUrl', $this->getCallbackUrl());
        $this->setParameter('extra', $this->setRemark($rechargeOrder));
        $this->setParameter('summary', "uuupays");
        $this->setParameter('clientIp', request()->getClientIp());
    }

    public function isReturnInCallback(array $data)
    {
        return $data['notifyType'] == 0 ? true : false;
    }

    public function qrCode(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement qrCode() method.
        $this->initParameters($rechargeOrder);
        $this->setParameter('service', 'TRADE.SCANPAY');
        $this->setParameter('sign', $this->paySign());
        $res = curlHttp($this->getGwPay(), $this->getParameters());
        if ($res['http_code'] == 200) {
            $res['body'] = convertToUTF8( $res['body']);
            preg_match('{<code>(.*?)</code>}', $res['body'], $match);
            $resCode = $match[1];
            preg_match('{<desc>(.*?)</desc>}', $res['body'], $match);
            $resDesc = $match[1];
            if ($resCode == '00') {
                preg_match('{<qrCode>(.*?)</qrCode>}', $res['body'], $match);
                $parseQrCode = $match[1];
                return new QrCodeAction($parseQrCode ? base64_decode($parseQrCode) : '');
            }
            throw new RechargeGatewayException($this, $res['body'], "取码错误:". $resDesc, Code::RECHARGE_THIRD_LOG);
        }
    }

    public function wapReq(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement wapReq() method.
        $this->initParameters($rechargeOrder);
        $this->setParameter('service', 'TRADE.H5PAY');
        $this->setParameter('sign', $this->paySign());
        return new HtmlPrintAction(formPostHtml($this->getGwPay(), $this->getParameters()));
    }

    public function getBankSign()
    {
        $signStr = 'service=' . $this->getParameter('service') . '&';
        $signStr .= 'version=' . $this->getParameter('version') . '&';
        $signStr .= 'merId=' . $this->getParameter('merId') . '&';
        $signStr .= 'tradeNo=' . $this->getParameter('tradeNo') . '&';
        $signStr .= 'tradeDate=' . $this->getParameter('tradeDate') . '&';
        $signStr .= 'amount=' . $this->getParameter('amount') . '&';
        $signStr .= 'notifyUrl=' . $this->getParameter('notifyUrl') . '&';
        $signStr .= 'extra=' . $this->getParameter('extra') . '&';
        $signStr .= 'summary=' . $this->getParameter('summary') . '&';
        $signStr .= 'clientIp=' . $this->getParameter('clientIp') . '&';
        $signStr .= 'bankId=' . $this->getParameter('bankId');
        $signStr .= $this->getMchKey();
        return strtoupper(md5($signStr));
    }
}